package com.fms.fmsapi.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fms.fmsapi.common.config.WxConfig;
import com.fms.fmsapi.entity.Role;
import com.fms.fmsapi.entity.User;
import com.fms.fmsapi.entity.result.UserResult;
import com.fms.fmsapi.mapper.RoleMapper;
import com.fms.fmsapi.service.UserService;
import com.fms.fmsapi.mapper.UserMapper;
import com.fms.fmsapi.utils.FetchGet;
import com.fms.fmsapi.utils.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

/**
* @author 24338
* @description 针对表【t_user】的数据库操作Service实现
* @createDate 2024-03-29 10:59:34
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
    implements UserService{
    private static final String CHARACTERS = "abcdefghijklmnopqrstuvwxyz0123456789*-";
    @Autowired
    WxConfig wxConfig;
    @Autowired
    UserMapper userMapper;

    @Autowired
    RoleMapper roleMapper;
    @Override
    public Map<String,String> login(String code, String nickname) {
        Map<String,String> res = new HashMap<>();
        Map<String, String> wxOpenid = getWxOpenid(code);
        if(wxOpenid==null||wxOpenid.get("openid")==null){
            return null;
        }
        //先查询opneId是否存在
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        lqw.eq(User::getOpenid,wxOpenid.get("openid"));
        User user = userMapper.selectOne(lqw);
        if(user!=null){//如果不等于null则说明用户已经注册过，则直接登录即可
            Role role = roleMapper.selectOne(new LambdaQueryWrapper<Role>().eq(Role::getUuid, user.getRoleId()));
            String token = JwtUtil.creatToken(user);
            res.put("token",token);
            res.put("roleName",role!=null? role.getName():"暂无角色");
            return res;
        } else{ //如果不存在则说明，用户还未注册，则执行注册操作
            boolean flag = register(wxOpenid.get("openid"), nickname);
            if(flag){
                user = userMapper.selectOne(lqw);
                if(user!=null){
                    String token = JwtUtil.creatToken(user);
                    res.put("token",token);
                    res.put("roleName","暂无角色");
                    return res;
                }
            }
        }
        return null;
    }

    @Override
    public List<UserResult> list(String keyword) {
        return userMapper.listAllByNickName(keyword);
    }

    public boolean register(String openid,String nickname){
        User user = new User();
        user.setNickName(nickname);
        user.setOpenid(openid);
        user.setUsername(generateRandomUsername(10));//默认生成一个用户名
        int insert = userMapper.insert(user);
        return insert>0?true:false;
    }

    public static String generateRandomUsername(int length) {
        StringBuilder username = new StringBuilder();
        Random random = new Random();

        for (int i = 0; i < length; i++) {
            int index = random.nextInt(CHARACTERS.length());
            username.append(CHARACTERS.charAt(index));
        }

        return username.toString();
    }

    public Map<String,String> getWxOpenid(String code){
        String url = "https://api.weixin.qq.com/sns/jscode2session";
        FetchGet<String> fetchGet = new FetchGet<>();
        fetchGet.setUrl(url);
        //设置请求参数
        MultiValueMap<String,String> queryParams = new LinkedMultiValueMap<>();
        queryParams.set("appid", wxConfig.getAppid());
        queryParams.set("secret", wxConfig.getSecret());
        queryParams.set("js_code",code);
        queryParams.set("grant_type","authorization_code");
        fetchGet.setQueryParams(queryParams);
        String fetch = fetchGet.fetch(String.class);
        return parseJsonToMap(fetch);
    }

    public static Map<String, String> parseJsonToMap(String jsonString) {
        ObjectMapper mapper = new ObjectMapper();
        try {
            return mapper.readValue(jsonString, new TypeReference<Map<String, String>>(){});
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }
}




